<template>
  <div class="message-notification" @click="toggleMessagePanel">
    <!-- 消息图标 -->
    <div class="message-icon">
      <div class="icon">💬</div>
      
      <!-- 未读消息数量提示 -->
      <transition name="bounce">
        <div v-if="unreadCount > 0" class="unread-badge">
          {{ unreadCount > 99 ? '99+' : unreadCount }}
        </div>
      </transition>
    </div>
    
    <!-- 消息面板 -->
    <transition name="slide">
      <div v-if="isPanelOpen" class="message-panel" ref="messageListRef">
        <div class="panel-header">
          <h3>消息通知</h3>
          <div class="connection-status">
            <span :class="['status-dot', connectionStatus]"></span>
            <span class="status-text">{{ getStatusText() }}</span>
          </div>
          <button 
            class="mark-all-btn"
            @click.stop="markAllAsRead"
            :disabled="unreadCount === 0 || loading"
          >
            {{ loading ? '处理中...' : '全部已读' }}
          </button>
        </div>
        
        <div class="panel-content">
          <div v-if="loading" class="loading-messages">
            <div class="loading-spinner"></div>
            <p>加载中...</p>
          </div>
          
          <div v-else-if="messages.length === 0" class="no-messages">
            <div class="no-messages-icon">📭</div>
            <p>暂无消息</p>
          </div>
          
          <div v-else class="messages-list">
            <div 
              v-for="message in sortedMessages" 
              :key="message.id"
              class="message-item"
              :class="{ unread: !message.read }"
              @click.stop="handleMessageClick(message)"
            >
              <div class="message-avatar">
                <div v-if="message.type === 'system'" class="avatar-icon">⚙️</div>
                <div v-else-if="message.type === 'course'" class="avatar-icon">📚</div>
                <div v-else class="avatar-icon">👤</div>
              </div>
              
              <div class="message-content">
                <div class="message-title">{{ message.title }}</div>
                <div class="message-text">{{ message.content }}</div>
                <div class="message-time">{{ formatTime(message.time) }}</div>
              </div>
              
              <div v-if="!message.read" class="unread-indicator"></div>
            </div>
          </div>
        </div>
      </div>
    </transition>
  </div>

  <!-- 详情弹窗 -->
  <div v-if="isDetailOpen" class="modal-overlay" @click="isDetailOpen = false">
    <div class="modal-dialog" @click.stop>
      <div class="modal-header">
        <h3>{{ selectedMessage?.title || '消息详情' }}</h3>
        <button class="close-btn" @click="isDetailOpen = false">×</button>
      </div>
      <div class="modal-body">
        <div v-if="selectedMessage">
          <div class="detail-time">{{ formatTime(selectedMessage.time) }}</div>
          <div class="detail-content">{{ selectedMessage.content }}</div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="confirm-btn" @click="isDetailOpen = false">知道了</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'

// 响应式数据
const isPanelOpen = ref(false)
const messages = ref([])
const isDetailOpen = ref(false)
const selectedMessage = ref(null)
const loading = ref(false)
const messageListRef = ref(null)
const connectionStatus = ref('disconnected') // 'connected', 'connecting', 'disconnected', 'error'

// SSE相关
let eventSource = null
let reconnectTimer = null
let reconnectAttempts = 0
const maxReconnectAttempts = 5
const reconnectInterval = 3000

// 计算属性
const unreadCount = computed(() => {
  return messages.value.filter(msg => !msg.read).length
})

const sortedMessages = computed(() => {
  return [...messages.value].sort((a, b) => {
    return new Date(b.time) - new Date(a.time)
  })
})

// 获取连接状态文本
const getStatusText = () => {
  switch (connectionStatus.value) {
    case 'connected': return '已连接'
    case 'connecting': return '连接中...'
    case 'disconnected': return '已断开'
    case 'error': return '连接错误'
    default: return '未知状态'
  }
}

// SSE连接管理
const connectSSE = () => {
  const storedUserId = localStorage.getItem('userId')
  const userId = storedUserId ? Number(storedUserId) : 22
  
  if (eventSource) {
    eventSource.close()
  }
  
  console.log(`🔗 正在建立SSE连接，用户ID: ${userId}`)
  console.log('🔗 SSE连接详情:', {
    userId: userId,
    url: `/sse/subscribe/${userId}`,
    fullUrl: `${window.location.origin}/sse/subscribe/${userId}`,
    proxyTarget: 'http://127.0.0.1:9003/sse/subscribe/' + userId
  })
  connectionStatus.value = 'connecting'
  
  try {
    eventSource = new EventSource(`/sse/subscribe/${userId}`)
    
    eventSource.onopen = () => {
      console.log('SSE连接已建立')
      connectionStatus.value = 'connected'
      reconnectAttempts = 0
      
      // 连接成功后不立即获取消息，等待SSE推送或用户主动打开面板
      console.log('SSE连接成功，等待消息推送或用户操作')
    }
    
    eventSource.onmessage = (event) => {
      console.log('📨 收到SSE原始消息:', event.data)
      console.log('📨 SSE事件详情:', {
        data: event.data,
        type: event.type,
        lastEventId: event.lastEventId,
        origin: event.origin
      })
      
      try {
        const data = JSON.parse(event.data)
        handleSSEMessage(data)
      } catch (error) {
        console.error('❌ 解析SSE消息失败:', error)
        console.error('🔍 原始消息内容:', event.data)
        console.error('🔍 消息类型:', typeof event.data)
      }
    }
    
    eventSource.onerror = (error) => {
      console.error('SSE连接错误:', error)
      connectionStatus.value = 'error'
      
      // 自动重连
      if (reconnectAttempts < maxReconnectAttempts) {
        reconnectAttempts++
        console.log(`SSE重连尝试 ${reconnectAttempts}/${maxReconnectAttempts}`)
        
        reconnectTimer = setTimeout(() => {
          connectSSE()
        }, reconnectInterval * reconnectAttempts) // 递增延迟
      } else {
        console.log('SSE重连次数已达上限，停止重连')
        connectionStatus.value = 'disconnected'
      }
    }
    
  } catch (error) {
    console.error('创建SSE连接失败:', error)
    connectionStatus.value = 'error'
  }
}

// 防抖处理 - 避免频繁调用fetchMessages
let fetchMessagesTimer = null
const debouncedFetchMessages = (preserveScrollPosition = true) => {
  if (fetchMessagesTimer) {
    clearTimeout(fetchMessagesTimer)
  }
  fetchMessagesTimer = setTimeout(() => {
    fetchMessages(preserveScrollPosition)
    fetchMessagesTimer = null
  }, 300) // 300ms防抖
}

// 防抖处理 - 避免频繁调用refreshClassList
let refreshClassTimer = null
const debouncedRefreshClassList = () => {
  if (refreshClassTimer) {
    clearTimeout(refreshClassTimer)
  }
  refreshClassTimer = setTimeout(() => {
    refreshClassList()
    refreshClassTimer = null
  }, 500) // 500ms防抖
}

// 刷新班级列表的方法
const refreshClassList = async () => {
  try {
    console.log('🔄 开始刷新班级列表...')
    
    // 获取用户的班级ID
    const userId = localStorage.getItem('userId') || '2'
    
    const url = `http://127.0.0.1:9001/user/class/getUserClassId?userId=${encodeURIComponent(userId)}`
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('userToken') || ''}`,
        'Content-Type': 'application/json'
      }
    })
    
    if (response.ok) {
      const result = await response.json()
      if (result.success && result.data) {
        const classId = result.data
        // 更新localStorage中的班级ID
        localStorage.setItem('classId', classId)
        console.log('✅ 班级列表刷新成功，classId:', classId)
        
        // 触发自定义事件，通知其他组件班级信息已更新
        window.dispatchEvent(new CustomEvent('classListRefreshed', { 
          detail: { classId } 
        }))
      }
    }
  } catch (error) {
    console.error('❌ 刷新班级列表失败:', error)
  }
}

// 处理SSE推送的消息
const handleSSEMessage = (data) => {
  console.log('🔔 处理SSE推送消息:', data)
  console.log('🔍 SSE消息详细信息:', {
    messageType: data.messageType,
    userId: data.userId,
    content: data.content,
    timestamp: data.timestamp,
    rawData: data
  })
  
  // 统一处理所有消息类型 - 使用防抖避免重复调用
  if (data.messageType === 'MESSAGE' || data.messageType === 'UPDATE_MESSAGE') {
    console.log('✅ 收到消息更新通知，准备刷新消息列表和班级列表')
    debouncedFetchMessages(true)
    // 同时刷新班级列表
    debouncedRefreshClassList()
  } else {
    console.warn('⚠️ 收到未处理的SSE消息类型:', data.messageType, '完整数据:', data)
    // 对于未知类型也尝试刷新，以防遗漏
    if (data.messageType) {
      console.log('🔄 尝试处理未知消息类型，触发刷新')
      debouncedFetchMessages(true)
      debouncedRefreshClassList()
    }
  }
}

// 断开SSE连接
const disconnectSSE = () => {
  if (eventSource) {
    eventSource.close()
    eventSource = null
  }
  
  if (reconnectTimer) {
    clearTimeout(reconnectTimer)
    reconnectTimer = null
  }
  
  connectionStatus.value = 'disconnected'
  console.log('SSE连接已断开')
}

// 切换消息面板显示/隐藏
const toggleMessagePanel = async () => {
  isPanelOpen.value = !isPanelOpen.value
  
  if (isPanelOpen.value) {
    // 打开面板时，如果SSE未连接，则建立连接
    if (connectionStatus.value === 'disconnected' || connectionStatus.value === 'error') {
      connectSSE()
    } else {
      // 已连接则直接获取消息
      await fetchMessages()
    }
  }
}

// 标记所有消息为已读
const markAllAsRead = async () => {
  try {
    loading.value = true
    const unreadMessages = messages.value.filter(msg => !msg.read)
    for (const message of unreadMessages) {
      await updateMessageIsRead(message.id)
      // 立即更新本地状态，无需等待SSE推送
      message.read = true
    }
    console.log('批量标记已读完成，等待SSE推送确认')
  } catch (error) {
    console.error('批量标记已读失败', error)
  } finally {
    loading.value = false
  }
}

// 调用后端接口更新已读状态
const updateMessageIsRead = async (id) => {
  try {
    const url = new URL('/message/updateMessageIsRead', window.location.origin)
    url.searchParams.set('messageId', String(id))
    url.searchParams.set('_t', Date.now().toString())
    
    const response = await fetch(url.toString(), {
      method: 'GET',
      headers: {
        'custom-header': 'application/json',
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'
      }
    })
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }
    
    const result = await response.text()
    console.log('标记消息为已读 - 响应内容:', result)
    
  } catch (err) {
    console.error('标记已读失败', err)
    throw err
  }
}

// 标记单个消息为已读
const markAsRead = async (id) => {
  const message = messages.value.find(msg => msg.id === id)
  if (message && !message.read) {
    try {
      await updateMessageIsRead(id)
      // 立即更新本地状态，无需等待SSE推送
      message.read = true
      console.log('单条消息标记已读完成，等待SSE推送确认:', id)
    } catch (error) {
      console.error('标记已读失败', error)
    }
  }
}

// 点击消息：标记已读并打开详情
const handleMessageClick = async (message) => {
  await markAsRead(message.id)
  selectedMessage.value = message
  isDetailOpen.value = true
}

// 格式化时间显示
const formatTime = (time) => {
  if (!time) return ''
  
  const now = new Date()
  const messageTime = new Date(time)
  const diff = now - messageTime
  
  if (diff < 60000) {
    return '刚刚'
  } else if (diff < 3600000) {
    return `${Math.floor(diff / 60000)}分钟前`
  } else if (diff < 86400000) {
    return `${Math.floor(diff / 3600000)}小时前`
  } else if (diff < 604800000) {
    return `${Math.floor(diff / 86400000)}天前`
  } else {
    return `${messageTime.getFullYear()}-${String(messageTime.getMonth() + 1).padStart(2, '0')}-${String(messageTime.getDate()).padStart(2, '0')}`
  }
}

// 从后端获取消息列表
const fetchMessages = async (preserveScrollPosition = false) => {
  try {
    let scrollTop = 0
    let scrollHeight = 0
    let clientHeight = 0
    
    if (preserveScrollPosition && messageListRef.value) {
      const container = messageListRef.value.querySelector('.panel-content')
      if (container) {
        scrollTop = container.scrollTop
        scrollHeight = container.scrollHeight
        clientHeight = container.clientHeight
      }
    }
    
    loading.value = true
    const storedUserId = localStorage.getItem('userId')
    const toUser = storedUserId ? Number(storedUserId) : 22
    
    const url = new URL('/message/getMessage', window.location.origin)
    url.searchParams.set('toUserid', String(toUser))
    url.searchParams.set('_t', Date.now().toString())

    const response = await fetch(url.toString(), {
      method: 'GET',
      headers: {
        'custom-header': 'application/json',
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'
      }
    })

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }

    const resJson = await response.json()
    const data = Array.isArray(resJson) ? resJson : (resJson?.data ?? [])

    console.log('获取消息列表 - SSE版本:', {
      requestTime: new Date().toLocaleTimeString(),
      url: url.toString(),
      dataLength: data.length
    })

    const newMessages = data.map(msg => {
      const readStatus = msg.isRead ?? msg.is_read ?? msg.read ?? msg.status ?? 0
      
      let isMessageRead = false
      
      if (readStatus !== null && readStatus !== undefined) {
        if (typeof readStatus === 'string') {
          isMessageRead = readStatus === '1' || readStatus.toLowerCase() === 'true' || readStatus.toLowerCase() === 'read'
        } else if (typeof readStatus === 'number') {
          isMessageRead = readStatus === 1
        } else if (typeof readStatus === 'boolean') {
          isMessageRead = readStatus
        }
      }
      
      return {
        id: msg.messageid,
        title: `用户${msg.fromUser || '未知'}`,
        time: new Date(msg.sendTime),
        content: msg.content || '',
        read: isMessageRead,
        type: 'user'
      }
    })
    
    messages.value = newMessages
    
    // 恢复滚动位置
    if (preserveScrollPosition && messageListRef.value) {
      await nextTick()
      const container = messageListRef.value.querySelector('.panel-content')
      if (container) {
        const newScrollHeight = container.scrollHeight
        const heightDiff = newScrollHeight - scrollHeight
        
        if (heightDiff !== 0) {
          const wasNearTop = scrollTop <= 50
          if (wasNearTop) {
            container.scrollTop = 0
          } else {
            container.scrollTop = scrollTop + heightDiff
          }
        } else {
          container.scrollTop = scrollTop
        }
      }
    }
  } catch (err) {
    console.error('获取消息列表失败', err)
  } finally {
    loading.value = false
  }
}

// 点击其他地方关闭面板
const handleClickOutside = (event) => {
  const panel = document.querySelector('.message-panel')
  const icon = document.querySelector('.message-icon')
  
  if (panel && !panel.contains(event.target) && icon && !icon.contains(event.target)) {
    isPanelOpen.value = false
  }
}

// 页面聚焦时重连SSE（如果需要）
const handleWindowFocus = () => {
  if (connectionStatus.value === 'disconnected' || connectionStatus.value === 'error') {
    console.log('页面重新聚焦，尝试重连SSE')
    connectSSE()
  }
}

// 页面失去焦点时不断开连接，保持后台接收消息
const handleWindowBlur = () => {
  console.log('页面失去焦点，SSE连接保持')
  // 不断开连接，这样用户在其他标签页时仍能收到消息通知
}

// 组件挂载
onMounted(async () => {
  document.addEventListener('click', handleClickOutside)
  window.addEventListener('focus', handleWindowFocus)
  window.addEventListener('blur', handleWindowBlur)
  
  // 建立SSE连接
  connectSSE()
})

// 组件卸载
onBeforeUnmount(() => {
  document.removeEventListener('click', handleClickOutside)
  window.removeEventListener('focus', handleWindowFocus)
  window.removeEventListener('blur', handleWindowBlur)
  
  // 清理防抖定时器
  if (fetchMessagesTimer) {
    clearTimeout(fetchMessagesTimer)
    fetchMessagesTimer = null
  }
  
  if (refreshClassTimer) {
    clearTimeout(refreshClassTimer)
    refreshClassTimer = null
  }
  
  // 断开SSE连接
  disconnectSSE()
})
</script>

<style scoped>
.message-notification {
  position: fixed;
  bottom: 100px;
  right: 30px;
  z-index: 1000;
}

.message-icon {
  width: 56px;
  height: 56px;
  background: #3b82f6;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
  position: relative;
  transition: all 0.3s ease;
}

.message-icon:hover {
  background: #2563eb;
  transform: scale(1.05);
  box-shadow: 0 6px 16px rgba(59, 130, 246, 0.4);
}

.message-icon .icon {
  color: white;
  font-size: 24px;
}

.unread-badge {
  position: absolute;
  top: -8px;
  right: -8px;
  background: #ef4444;
  color: white;
  border-radius: 10px;
  padding: 2px 6px;
  font-size: 12px;
  font-weight: bold;
  min-width: 20px;
  text-align: center;
  box-shadow: 0 2px 6px rgba(239, 68, 68, 0.3);
}

.message-panel {
  position: absolute;
  bottom: 70px;
  right: 0;
  width: 380px;
  background: white;
  border-radius: 12px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  transform-origin: bottom right;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid #e5e7eb;
  background: #f9fafb;
}

.panel-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
}

.connection-status {
  display: flex;
  align-items: center;
  gap: 6px;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  transition: all 0.3s ease;
}

.status-dot.connected {
  background: #10b981;
  box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.3);
}

.status-dot.connecting {
  background: #f59e0b;
  animation: pulse 1.5s infinite;
}

.status-dot.disconnected {
  background: #6b7280;
}

.status-dot.error {
  background: #ef4444;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.status-text {
  font-size: 12px;
  color: #6b7280;
}

.mark-all-btn {
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.2s;
}

.mark-all-btn:hover:not(:disabled) {
  background: #2563eb;
}

.mark-all-btn:disabled {
  background: #9ca3af;
  cursor: not-allowed;
}

.panel-content {
  max-height: 400px;
  overflow-y: auto;
}

.loading-messages {
  text-align: center;
  padding: 40px 20px;
  color: #6b7280;
}

.loading-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid #e5e7eb;
  border-top: 3px solid #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 16px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.no-messages {
  text-align: center;
  padding: 40px 20px;
  color: #6b7280;
}

.no-messages-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.no-messages p {
  margin-top: 16px;
  font-size: 16px;
}

.messages-list {
  padding: 10px 0;
}

.message-item {
  display: flex;
  padding: 16px 20px;
  border-bottom: 1px solid #f3f4f6;
  cursor: pointer;
  position: relative;
  transition: background-color 0.2s;
}

.message-item:hover {
  background-color: #f9fafb;
}

.message-item.unread {
  background-color: #eff6ff;
}

.message-item.unread:hover {
  background-color: #dbeafe;
}

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #e0f2fe;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
  flex-shrink: 0;
}

.avatar-icon {
  font-size: 20px;
}

.message-content {
  flex: 1;
  min-width: 0;
}

.message-title {
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 4px;
  font-size: 14px;
}

.message-text {
  color: #4b5563;
  font-size: 13px;
  margin-bottom: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.message-time {
  font-size: 12px;
  color: #9ca3af;
}

.unread-indicator {
  width: 8px;
  height: 8px;
  background: #3b82f6;
  border-radius: 50%;
  position: absolute;
  top: 50%;
  right: 20px;
  transform: translateY(-50%);
}

/* 模态框样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}

.modal-dialog {
  background: white;
  border-radius: 12px;
  width: 520px;
  max-width: 90vw;
  max-height: 80vh;
  overflow: hidden;
  box-shadow: 0 20px 25px rgba(0, 0, 0, 0.15);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid #e5e7eb;
  background: #f9fafb;
}

.modal-header h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
}

.close-btn {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #6b7280;
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
}

.close-btn:hover {
  background: #e5e7eb;
  color: #374151;
}

.modal-body {
  padding: 20px;
  max-height: 400px;
  overflow-y: auto;
}

.detail-time {
  font-size: 12px;
  color: #9ca3af;
  margin-bottom: 12px;
}

.detail-content {
  font-size: 14px;
  line-height: 1.6;
  color: #374151;
  white-space: pre-wrap;
}

.modal-footer {
  padding: 20px;
  border-top: 1px solid #e5e7eb;
  display: flex;
  justify-content: flex-end;
}

.confirm-btn {
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 10px 20px;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s;
}

.confirm-btn:hover {
  background: #2563eb;
}

/* 动画效果 */
.bounce-enter-active {
  animation: bounce-in 0.5s;
}

.bounce-leave-active {
  animation: bounce-in 0.5s reverse;
}

@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.slide-enter-active,
.slide-leave-active {
  transition: all 0.3s ease;
}

.slide-enter-from,
.slide-leave-to {
  opacity: 0;
  transform: scale(0.9) translateX(20px);
}
</style>
